import { HttpMethod, HttpError } from '../types/http';
import type { RequestConfig, RequestInterceptor, ResponseInterceptor, ApiResponse } from '../types/http';

export class HttpClient {
  private baseConfig: RequestConfig;
  private requestInterceptors: RequestInterceptor[] = [];
  private responseInterceptors: ResponseInterceptor[] = [];

  constructor(config: Partial<RequestConfig> = {}) {
    this.baseConfig = {
      baseURL: '',
      timeout: 60000,
      headers: {},
      ...config
    } as RequestConfig;
  }

  // 添加请求拦截器
  addRequestInterceptor(interceptor: RequestInterceptor): void {
    this.requestInterceptors.push(interceptor);
  }

  // 添加响应拦截器
  addResponseInterceptor(interceptor: ResponseInterceptor): void {
    this.responseInterceptors.push(interceptor);
  }

  // 处理请求配置
  private async processRequestConfig(config: RequestConfig): Promise<RequestConfig> {
    let processedConfig = { ...this.baseConfig, ...config };

    for (const interceptor of this.requestInterceptors) {
      if (interceptor.onRequest) {
        processedConfig = await interceptor.onRequest(processedConfig);
      }
    }

    return processedConfig;
  }

  // 处理响应
  private async processResponse(response: any): Promise<any> {
    let processedResponse = response;

    for (const interceptor of this.responseInterceptors) {
      if (interceptor.onResponse) {
        processedResponse = await interceptor.onResponse(processedResponse);
      }
    }

    return processedResponse;
  }

  // 处理错误
  private async processError(error: any): Promise<never> {
    let processedError = error;

    for (const interceptor of this.responseInterceptors) {
      if (interceptor.onResponseError) {
        processedError = await interceptor.onResponseError(processedError);
      }
    }

    throw processedError;
  }

  // 发送请求
  private async request<T>(config: RequestConfig): Promise<ApiResponse<T>> {
    try {
      const processedConfig = await this.processRequestConfig(config);
      const { baseURL, url, ...uniConfig } = processedConfig;
      const finalUrl = baseURL ? `${baseURL}${url}` : url;
      
      return new Promise((resolve, reject) => {
        uni.request({
          ...uniConfig,
          url: finalUrl!,
          success: async (response: any) => {
            try {
              const processedResponse = await this.processResponse(response);
              if (processedResponse.statusCode >= 200 && processedResponse.statusCode < 300) {
                resolve(processedResponse.data);
              } else {
                reject(new HttpError(processedResponse.statusCode, 'Request failed', processedResponse.data));
              }
            } catch (error) {
              reject(error);
            }
          },
          fail: (error) => {
            this.processError(error).catch(reject);
          }
        });
      });
    } catch (error) {
      return this.processError(error);
    }
  }

  // HTTP方法封装
  async get<T>(url: string, config: Partial<Omit<RequestConfig, 'url' | 'method'>> = {}): Promise<ApiResponse<T>> {
    return this.request<T>({ ...config, url, method: HttpMethod.GET } as RequestConfig);
  }

  async post<T>(url: string, data?: any, config: Partial<Omit<RequestConfig, 'url' | 'method' | 'data'>> = {}): Promise<ApiResponse<T>> {
    return this.request<T>({ ...config, url, method: HttpMethod.POST, data } as RequestConfig);
  }
} 